from django.shortcuts import render
from django.http import HttpRequest, HttpResponse
from django.views.generic import View
from rest_framework.views import APIView
from rest_framework.decorators import api_view
from rest_framework.request import Request
from apps.generate_secret.models import AppSecret
# from apps.generate_secret.tools import validate_signature_token
from utils.common_tools import get_client_ip, validate_signature, validate_signature_token
from utils.crypto_tools import command_genkey
from utils.jsonResponse import SuccessResponse, ErrorResponse, DetailResponse
from apps.keys_management.models import RootKey, KeyAuditLog
# from apps.generate_secret.tools import validate_signature_token
from django.db.models import Q
import logging
from django.core.cache import cache
import json
import traceback
from datetime import datetime, timedelta

log = logging.getLogger('log')


class RootKeyViews(APIView):
    """
    根密钥管理API
    """
    
    def post(self, request: Request):
        """
        生成根密钥
        POST /keys/generateRoot
        请求体: {
            "key_type": "SM4",
            "key_length": 128,
            "description": "测试密钥"
        }
        头信息: {
            "APP-ID": "your_app_id",
            "TOKEN": "your_signature_token"
        }
        参数: {
            "senderNonce": "sender_nonce_value",
            "recipNonce": "recip_nonce_value", 
            "messageTime": "20250101000000000"
        }
        """
        client_ip = get_client_ip(request)
        request_id = f"req_{datetime.now().strftime('%Y%m%d%H%M%S%f')[:-3]}"
        headers = dict(request.headers)
        body = json.loads(request.body)
        env = body.get('env', 'prod') # dev, prod 
        
        log.info(f"[{request_id}] 开始处理生成根密钥请求 - IP: {client_ip}, 路径: {request.path}")
        log.info(f"[{request_id}] ====请求头信息: {headers}")
        log.info(f"[{request_id}] ====请求body: {body}")
        
        # 签名校验
        is_valid, error_msg = validate_signature(headers, body)
        if not is_valid:
            log.warning(f"[{request_id}] 签名校验失败: {error_msg}")
            return ErrorResponse(data=f"签名校验失败: {error_msg}")
        
        log.info(f"[{request_id}] 签名校验通过，开始处理业务逻辑")
        
        try:
            # 记录请求体
            # request_body = request.body.decode('utf-8') 
            # log.info(f"[{request_id}] 请求体: {request_body}")
            
            data = json.loads(request.body) if request.body else {}
            key_type = data.get('key_type')
            key_length = data.get('key_length')
            description = data.get('description', '')

            log.info(f"[{request_id}] 解析参数 - key_type: {key_type}, key_length: {key_length}, description: {description}")

            # 参数验证
            if not key_type:
                log.warning(f"[{request_id}] 参数验证失败: key_type参数不能为空")
                return ErrorResponse(data="key_type参数不能为空")
            if key_type not in ['SM1', 'SM4']:
                log.warning(f"[{request_id}] 参数验证失败: key_type参数必须是SM1或SM4，当前值: {key_type}")
                return ErrorResponse(data="key_type参数必须是SM1或SM4")
            if not key_length:
                log.warning(f"[{request_id}] 参数验证失败: key_length参数不能为空")
                return ErrorResponse(data="key_length参数不能为空")
            if key_length != 128 :
                log.warning(f"[{request_id}] 参数验证失败: key_length参数必须是128，当前值: {key_length}")
                return ErrorResponse(data="key_length参数必须是128")

            log.info(f"[{request_id}] 参数验证通过，开始生成根密钥")

            # 生成根密钥
            key_id = RootKey.generate_key_id()
            if env == 'dev':
                root_key = RootKey.generate_root_key(key_length)
            else:
                status, root_key = command_genkey(key_type)
                if status != 0:
                    log.error(f"[{request_id}] 根密钥生成失败: {root_key}")
                    return ErrorResponse(code=status, data=None, msg=f"根密钥生成失败: {root_key}")
            version = RootKey.generate_version()

            log.info(f"[{request_id}] 生成密钥信息 - key_id: {key_id}, key长度: {len(root_key)}, version: {version}")
            app_id = headers.get('Appid')
            app_secret_obj = AppSecret.objects.filter(app_id=app_id, is_delete=False, status=True).first()

            # 创建根密钥记录
            root_key_obj = RootKey.objects.create(
                key_id=key_id,
                app_id = app_secret_obj,  # 从头信息获取app_id
                key=root_key,
                key_type=key_type,
                key_length=key_length,
                description=description,
                version=version,
                # expired_at=datetime.now() + timedelta(days=365)  # 默认1年过期
            )

            # 记录审计日志
            # KeyAuditLog.objects.create(
            #     key_id=key_id,
            #     operation='create',
            #     operator_ip=client_ip,
            #     operation_details=f"创建根密钥 - 类型: {key_type}, 长度: {key_length}, 描述: {description}"
            # )

            result = {
                "key_id": key_id,
                "key": root_key,
                "key_type": key_type,
                "key_length": key_length,
                "description": description,
                "created_at": root_key_obj.created_at.strftime("%Y%m%d%H%M%S%f")[:-3],
                "version": version,
                "status": root_key_obj.status
            }

            log.info(f"[{request_id}] 根密钥生成成功 - key_id: {key_id}, key_type: {key_type}")

            return DetailResponse(data=result, msg="根密钥生成成功")

        except json.JSONDecodeError as e:
            log.error(f"[{request_id}] JSON解析失败: {str(e)}, 请求体: {body}")
            return ErrorResponse(data="请求体格式错误，请使用JSON格式")
        except Exception as e:
            log.error(f"[{request_id}] 生成根密钥失败: {str(e)}")
            log.error(f"[{request_id}] 异常堆栈: {traceback.format_exc()}")
            return ErrorResponse(data=f"生成根密钥失败: {str(e)}")
    
    def get(self, request: Request):
        """
        获取根密钥列表
        GET /keys/list?page=1&size=10&key_type=SM4&status=active
        """
        client_ip = self._get_client_ip(request)
        request_id = f"req_{datetime.now().strftime('%Y%m%d%H%M%S%f')[:-3]}"
        
        log.info(f"[{request_id}] 开始处理获取根密钥列表请求 - IP: {client_ip}, 路径: {request.path}")
        log.info(f"[{request_id}] 查询参数: {dict(request.GET)}")
        
        try:
            page = int(request.GET.get('page', 1))
            size = int(request.GET.get('size', 10))
            key_type = request.GET.get('key_type', '')
            status = request.GET.get('status', '')
            
            log.info(f"[{request_id}] 解析参数 - page: {page}, size: {size}, key_type: {key_type}, status: {status}")
            
            # 构建查询条件
            query = Q(is_delete=False)
            if key_type:
                query &= Q(key_type=key_type)
                log.info(f"[{request_id}] 添加密钥类型过滤条件: {key_type}")
            if status:
                query &= Q(status=status)
                log.info(f"[{request_id}] 添加状态过滤条件: {status}")
            
            # 查询总数
            total = RootKey.objects.filter(query).count()
            log.info(f"[{request_id}] 查询到总记录数: {total}")
            
            # 分页查询
            start = (page - 1) * size
            end = start + size
            root_keys = RootKey.objects.filter(query).order_by('-created_at')[start:end]
            
            result_list = []
            for root_key in root_keys:
                result_list.append({
                    "key_id": root_key.key_id,
                    "key_type": root_key.key_type,
                    "key_length": root_key.key_length,
                    "description": root_key.description,
                    "status": root_key.status,
                    "version": root_key.version,
                    "created_at": root_key.created_at.strftime("%Y%m%d%H%M%S%f")[:-3],
                    "expired_at": root_key.expired_at.strftime("%Y%m%d%H%M%S%f")[:-3] if root_key.expired_at else None
                })
            
            result = {
                "list": result_list,
                "total": total,
                "page": page,
                "size": size
            }
            
            log.info(f"[{request_id}] 根密钥列表查询成功 - 总数: {total}, 当前页: {page}, 每页大小: {size}")
            
            return DetailResponse(data=result, msg="获取根密钥列表成功")
            
        except ValueError as e:
            log.error(f"[{request_id}] 参数类型错误: {str(e)}")
            return ErrorResponse(data="分页参数必须是整数")
        except Exception as e:
            log.error(f"[{request_id}] 获取根密钥列表失败: {str(e)}")
            log.error(f"[{request_id}] 异常堆栈: {traceback.format_exc()}")
            return ErrorResponse(data=f"获取根密钥列表失败: {str(e)}")


class RootKeyDetailViews(APIView):
    """
    根密钥详情管理API
    """
    
    def _validate_signature(self, request: Request):
        """
        公共签名校验函数
        从头信息获取app_id和token，从参数获取senderNonce、recipNonce、messageTime
        调用validate_signature_token进行检测
        """
        # 从头信息获取app_id和token
        app_id = request.META.get('HTTP_APP_ID')
        token = request.META.get('HTTP_TOKEN')
        
        # 从请求参数获取其他参数
        sender_nonce = request.GET.get('senderNonce') or request.data.get('senderNonce')
        # recip_nonce = request.GET.get('recipNonce') or request.data.get('recipNonce')
        message_time = request.GET.get('messageTime') or request.data.get('messageTime')
        
        log.info(f"签名校验参数 - app_id: {app_id}, token长度: {len(token) if token else 0}, senderNonce: {sender_nonce}, recipNonce: {recip_nonce}, messageTime: {message_time}")
        
        # 参数校验
        if not app_id:
            log.warning("签名校验失败: 缺少app_id头信息")
            return False, "缺少app_id头信息"
        if not token:
            log.warning("签名校验失败: 缺少token头信息")
            return False, "缺少token头信息"
        if not sender_nonce:
            log.warning("签名校验失败: 缺少senderNonce参数")
            return False, "缺少senderNonce参数"
        # if not recip_nonce:
            # log.warning("签名校验失败: 缺少recipNonce参数")
            # return False, "缺少recipNonce参数"
        if not message_time:
            log.warning("签名校验失败: 缺少messageTime参数")
            return False, "缺少messageTime参数"
        
        # 调用validate_signature_token进行校验
        result = validate_signature_token(app_id, sender_nonce, message_time, token)
        if result[0]:
            log.info(f"签名校验成功 - app_id: {app_id}")
        else:
            log.warning(f"签名校验失败 - app_id: {app_id}, 错误: {result[1]}")
        return result
    
    def get(self, request: Request):
        """
        获取根密钥详情
        GET /keys/detail?key_id=xxx
        头信息: {
            "APP-ID": "your_app_id",
            "TOKEN": "your_signature_token"
        }
        参数: {
            "senderNonce": "sender_nonce_value",
            "recipNonce": "recip_nonce_value", 
            "messageTime": "20250101000000000"
        }
        """
        client_ip = self._get_client_ip(request)
        request_id = f"req_{datetime.now().strftime('%Y%m%d%H%M%S%f')[:-3]}"
        
        log.info(f"[{request_id}] 开始处理获取根密钥详情请求 - IP: {client_ip}, 路径: {request.path}")
        log.info(f"[{request_id}] 查询参数: {dict(request.GET)}")
        
        try:
            key_id = request.GET.get('key_id')
            if not key_id:
                log.warning(f"[{request_id}] 参数验证失败: key_id参数不能为空")
                return ErrorResponse(data="key_id参数不能为空")
            
            root_key_obj = RootKey.objects.filter(
                key_id=key_id,
                is_delete=False
            ).first()
            
            if not root_key_obj:
                log.warning(f"[{request_id}] 根密钥不存在 - key_id: {key_id}")
                return ErrorResponse(data="根密钥不存在")

            result = {
                "key_id": root_key_obj.key_id,
                "key": root_key_obj.key,
                "key_type": root_key_obj.key_type,
                "key_length": root_key_obj.key_length,
                "description": root_key_obj.description,
                "version": root_key_obj.version,
                "status": root_key_obj.status,
                "created_at": root_key_obj.created_at.strftime("%Y%m%d%H%M%S%f")[:-3],
                "updated_at": root_key_obj.updated_at.strftime("%Y%m%d%H%M%S%f")[:-3],
                "expired_at": root_key_obj.expired_at.strftime("%Y%m%d%H%M%S%f")[:-3] if root_key_obj.expired_at else None
            }

            log.info(f"[{request_id}] 根密钥详情查询成功 - key_id: {key_id}")

            return DetailResponse(data=result, msg="获取根密钥详情成功")

        except Exception as e:
            log.error(f"[{request_id}] 获取根密钥详情失败: {str(e)}")
            log.error(f"[{request_id}] 异常堆栈: {traceback.format_exc()}")
            return ErrorResponse(data=f"获取根密钥详情失败: {str(e)}")

    def put(self, request: Request):
        """
        更新根密钥状态
        PUT /keys/update
        请求体: {
            "key_id": "密钥ID",
            "status": "active/inactive",
            "description": "描述"
        }
        头信息: {
            "APP-ID": "your_app_id",
            "TOKEN": "your_signature_token"
        }
        参数: {
            "senderNonce": "sender_nonce_value",
            "recipNonce": "recip_nonce_value", 
            "messageTime": "20250101000000000"
        }
        """
        client_ip = self._get_client_ip(request)
        request_id = f"req_{datetime.now().strftime('%Y%m%d%H%M%S%f')[:-3]}"
        
        log.info(f"[{request_id}] 开始处理更新根密钥状态请求 - IP: {client_ip}, 路径: {request.path}")
        log.info(f"[{request_id}] 请求头信息: {dict(request.headers)}")
        
        # 签名校验
        is_valid, error_msg = self._validate_signature(request)
        if not is_valid:
            log.warning(f"[{request_id}] 签名校验失败: {error_msg}")
            return ErrorResponse(data=f"签名校验失败: {error_msg}")
        
        log.info(f"[{request_id}] 签名校验通过，开始处理业务逻辑")
        
        try:
            data = json.loads(request.body) if request.body else {}
            key_id = data.get('key_id')
            status = data.get('status')
            description = data.get('description', '')

            if not key_id:
                log.warning(f"[{request_id}] 参数验证失败: key_id参数不能为空")
                return ErrorResponse(data="key_id参数不能为空")

            root_key_obj = RootKey.objects.filter(
                key_id=key_id,
                is_delete=False
            ).first()

            if not root_key_obj:
                log.warning(f"[{request_id}] 根密钥不存在 - key_id: {key_id}")
                return ErrorResponse(data="根密钥不存在")

            if status and status in ['active', 'inactive']:
                root_key_obj.status = status
            if description:
                root_key_obj.description = description

            root_key_obj.update_by = request.user.username if hasattr(request, 'user') and request.user.is_authenticated else 'system'
            root_key_obj.save()

            # 记录审计日志
            KeyAuditLog.objects.create(
                key_id=key_id,
                operation='update',
                operator_ip=client_ip,
                operation_details=f"更新根密钥状态 - 状态: {status}, 描述: {description}"
            )

            log.info(f"[{request_id}] 根密钥状态更新成功 - key_id: {key_id}")

            return DetailResponse(data="根密钥状态更新成功", msg="根密钥状态更新成功")

        except json.JSONDecodeError as e:
            log.error(f"[{request_id}] JSON解析失败: {str(e)}, 请求体: {request.body}")
            return ErrorResponse(data="请求体格式错误，请使用JSON格式")
        except Exception as e:
            log.error(f"[{request_id}] 更新根密钥状态失败: {str(e)}")
            log.error(f"[{request_id}] 异常堆栈: {traceback.format_exc()}")
            return ErrorResponse(data=f"更新根密钥状态失败: {str(e)}")

    def _get_client_ip(self, request):
        """获取客户端IP地址"""
        x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
        if x_forwarded_for:
            ip = x_forwarded_for.split(',')[0]
        else:
            ip = request.META.get('REMOTE_ADDR')
        return ip
